package com.example.demo.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.UUID;

/**
 * Created by zhangting on 31/03/2021.
 */

@Service
@Slf4j
public class SendService implements RabbitTemplate.ConfirmCallback ,RabbitTemplate.ReturnsCallback {


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    private void init() {
        rabbitTemplate.setConfirmCallback(this);
//        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnsCallback(this);
    }

    public void send(String msg,String routkey){
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("exchange_name",routkey,msg,correlationData);
        log.info("---send {},{},{}",msg,routkey,correlationData.getId());
    }


    //此方法一般不用。除非需要类 rpc 调用。性能很差的。
    public void sendAndReceive(String msg,String routkey){
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
      Object o=  rabbitTemplate.convertSendAndReceive("exchange_name",routkey,msg,correlationData);
        log.info("---send {},{},{},{}",msg,routkey,correlationData.getId(),o);
    }

    //消息成功到达exchange会被调用。
    @Override
    public void confirm(@Nullable CorrelationData correlationData, boolean b, @Nullable String s) {
        if (b){
            log.info(" exchange received msg: {},correlation:{}",s,correlationData.getId());
        }else{
            log.error(" exchange did not received msg: {},correlation:{}",s,correlationData.getId());

        }

    }

    // 该方法在 消息没有到达指的queue时会被调用。或是失败到达queue，或是指定的queue不存。
    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {
        log.error("队列没收到消息=={},{},routkey:{}",returnedMessage.getMessage(),returnedMessage.getReplyCode(),returnedMessage.getRoutingKey());
    }
}
